package com.unibuy.smartdevice.ui.dialog;

import android.content.Context;
import android.graphics.Color;
import android.os.Handler;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.work.BackoffPolicy;
import androidx.work.ExistingWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;

import com.unibuy.smartdevice.DialogAbstract;
import com.unibuy.smartdevice.MyApp;
import com.unibuy.smartdevice.R;
import com.unibuy.smartdevice.controller.DevController;
import com.unibuy.smartdevice.controller.DevDigitalDisplayController;
import com.unibuy.smartdevice.controller.DevElectricController;
import com.unibuy.smartdevice.controller.DevFlowerController;
import com.unibuy.smartdevice.database.SlotsDao;
import com.unibuy.smartdevice.databinding.DialogDispatchBinding;
import com.unibuy.smartdevice.databinding.DialogFlowerPickupBinding;
import com.unibuy.smartdevice.devices.PortTools;
import com.unibuy.smartdevice.devices.SlotField;
import com.unibuy.smartdevice.exception.LogsEmptyException;
import com.unibuy.smartdevice.exception.LogsIOException;
import com.unibuy.smartdevice.exception.LogsParseException;
import com.unibuy.smartdevice.exception.LogsSecurityException;
import com.unibuy.smartdevice.exception.LogsSettingEmptyException;
import com.unibuy.smartdevice.exception.LogsUnsupportedOperationException;
import com.unibuy.smartdevice.external.HttpAPI;
import com.unibuy.smartdevice.structure.BuyStructure;
import com.unibuy.smartdevice.structure.DispatchStructure;
import com.unibuy.smartdevice.structure.ProductStructure;
import com.unibuy.smartdevice.structure.ReportDispatchInfoStructure;
import com.unibuy.smartdevice.structure.ReportFreeGiftCodeStructure;
import com.unibuy.smartdevice.structure.SlotStructure;
import com.unibuy.smartdevice.tools.HandlerMain;
import com.unibuy.smartdevice.tools.HandlerMainCountdown;
import com.unibuy.smartdevice.tools.ToastHandlerMain;
import com.unibuy.smartdevice.ui.FontendActivity;
import com.unibuy.smartdevice.ui.recycler.RecyclerDialogDispatchListAdpter;
import com.unibuy.smartdevice.ui.recycler.RecyclerDialogFlowerPickupListAdpter;
import com.unibuy.smartdevice.ui.tools.ImageGlide;

import org.json.JSONException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class FlowerPickupDialog extends DialogAbstract {
    public enum Option {
        TOAST(0),
        COUNTDOWN_CANCEL(1),
        SET_COUNTDOWN_TEXT(2),
        NEXT_PRODUCT(3),
        ENABLED_TRUE(4),
        ENABLED_FALSE(5),
        REPORT_DISPATCH(8),
        SET_MESSAGE_TEXT(9),
        CURRENTLY_PROCESSING_GOODS(71),
        SHIPPED_PROCESSING_GOODS(72),
        NEXT_PROCESS_GOODS(73),
        ERROR_PROCESS_GOODS(74),
        ;

        private int option;

        public int getOption() {
            return option;
        }

        Option(int option) {
            this.option = option;
        }
    }

    public static final Map<Integer, Option> optionMap = new HashMap<>();
    static {
        for (Option option : Option.values()) {
            optionMap.put(option.getOption(), option);
        }
    }

    @Override
    protected Context setCtx() {
        return getContext();
    }

    @Override
    protected Class<? extends DialogAbstract> setCls() {
        return getClass();
    }

    @Override
    protected HandlerMain setHandlerMain() {
        return new ToastHandlerMain(getCtx(), getLogs()) {

            @Override
            protected void execute(Context context, int commandCode, String message) {
                if (!optionMap.containsKey(commandCode)) {
                    getLogs().debug("key not found:" + commandCode);
                    return;
                }

                Option option = optionMap.get(commandCode);

                switch (option) {
                    case TOAST:
                        super.execute(context, commandCode, message);
                        break;
                    case COUNTDOWN_CANCEL:
                        cancelOnThreadCountdown();
                        break;
                    case SET_COUNTDOWN_TEXT:
                        setButtonOkText(Integer.parseInt(message));
                        if (Integer.parseInt(message) <= 15) {
                            setTextViewCountdown(Integer.parseInt(message),slot);
                        }
                        break;
                    case NEXT_PRODUCT:
                        //currentlyProcessingGoods();
                        break;
                    case ENABLED_TRUE:
                        openButtonOk();
                        break;
                    case ENABLED_FALSE:
                        closeButtonOk();
                        break;
                    case REPORT_DISPATCH:
                        if (isReportDispatch) {
                            try {
                                isReportDispatch = false;
                                new HttpAPI(getHandlerMain()).reportDispatchInfo(MyApp.getInstance().getReportDispatchInfoData());
                            } catch (LogsSettingEmptyException | LogsParseException e) {
                                getLogs().warning(e);
                            }
                        }
                        break;
                    case SET_MESSAGE_TEXT:
                        setTextViewSmall(message);
                        break;
                    case CURRENTLY_PROCESSING_GOODS:
                        //currentlyProcessingGoods();
                        break;
                    case SHIPPED_PROCESSING_GOODS:
                        //shippedProcessingGoods();
                        break;
                    case NEXT_PROCESS_GOODS:
                        //nextProcessGoods();
                        break;
                    case ERROR_PROCESS_GOODS:
                        if (!buttonControlCountdown.isShutdown()) {
                            buttonControlCountdown.shutdown();
                        }
                        buttonControlCountdown.start(10);

                        closeDialogCountdown.shutdown();
                        setTextViewSmall(message);
                        setButtonOkText(0);
                        break;
                }
            }
        };
    }

    private DialogFlowerPickupBinding binding;
    private RecyclerDialogFlowerPickupListAdpter recyclerDialogFlowerPickupListAdpter;
    private CloseDialogOnThreadHandler closeDialogCountdown;
    private List<DispatchStructure> dispatchList;
    private int dispatchIndex;
    private boolean isReportDispatch;
    private boolean isChangeStatus;
    private int countdownNumber = 15;
    private int slot;
    private HandlerMainCountdown buttonControlCountdown;
    private HttpAPI httpAPI;

    public FlowerPickupDialog(Context context, HandlerMain srcHandlerMain) {
        super(context, srcHandlerMain);
        dispatchList = new ArrayList<>();
        dispatchIndex = 0;
        isReportDispatch = true;
        isChangeStatus = true;
    }

    @Override
    protected void onCreate(Context context) {
        binding = DialogFlowerPickupBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        isReportDispatch = true;
        slot = 0;
        httpAPI = new HttpAPI(getHandlerMain());

        MyApp.getInstance().setReportFreeGiftCodeStructure(new ReportFreeGiftCodeStructure("", 0, "", 0, 0, ""));

        getLogs().info("BuyList size:" + MyApp.getInstance().getBuyList().size());

        for (BuyStructure buyStructure:  MyApp.getInstance().getBuyList()) {
            getLogs().info(buyStructure.toString());
            if (!buyStructure.getProduct().getMaterialCode().isEmpty() && buyStructure.getProduct().getMaterialCode().contains(":")) {
                String[] materialCodes = buyStructure.getProduct().getMaterialCode().split(":");
                String productId = materialCodes[0];
                int count = Integer.parseInt(materialCodes[1]);
                try {
                    SlotStructure slotData = MyApp.getInstance().getSlotData(buyStructure.getField(), buyStructure.getSlot());
                    if (slotData.getProduct().getProductID().equals(productId)) {
                        DispatchStructure dispatchData = new DispatchStructure(buyStructure.getField(), buyStructure.getSlot(), slotData.getProduct(), count*buyStructure.getCount());
                        dispatchData.setFreeGift(buyStructure.isFreeGift());
                        this.dispatchList.add(dispatchData);
                    }
                } catch (LogsEmptyException e) {
                    getLogs().warning(e);
                }
            } else {
                DispatchStructure dispatchData = new DispatchStructure(buyStructure.getField(), buyStructure.getSlot(), buyStructure.getProduct(), buyStructure.getCount());
                dispatchData.setFreeGift(buyStructure.isFreeGift());
                this.dispatchList.add(dispatchData);
            }
        }

        getLogs().info("DispatchList size:" + this.dispatchList.size());

        this.recyclerDialogFlowerPickupListAdpter = new RecyclerDialogFlowerPickupListAdpter(getCtx(), this.dispatchList, getHandlerMain());
        //this.binding.recyclerDialogFlowerPickupList.setAdapter(recyclerDialogFlowerPickupListAdpter);
        //this.binding.recyclerDialogFlowerPickupList.setLayoutManager(new LinearLayoutManager(context));
        /*開啟格子櫃*/
        try {
            openLatticeCabinet();
        } catch (LogsSecurityException e) {
            throw new RuntimeException(e);
        } catch (LogsUnsupportedOperationException e) {
            throw new RuntimeException(e);
        } catch (LogsIOException e) {
            throw new RuntimeException(e);
        }
        /*開啟格子櫃*/

        this.binding.buttonCancel.setOnClickListener(v -> {
//            getSrcHandlerMain().start(getClass().getSimpleName(), FontendActivity.Option.RESET_DATA.getOption(), "update data");
//
//            OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(UploadLogOneTimeWorker.class)
//                    .setInitialDelay(5, TimeUnit.SECONDS)
//                    .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 5, TimeUnit.MINUTES)
//                    .build();
//
//            WorkManager.getInstance(getCtx()).enqueueUniqueWork(
//                    "oneTimeWorkRequest",  // 設定唯一名稱，避免重複
//                    ExistingWorkPolicy.REPLACE,
//                    oneTimeWorkRequest
//            );
//
            getSrcHandlerMain().start(getClass().getSimpleName(), "@"+getCtx().getString(R.string.reported_please_contact_site_for_processing));//已回報，請現場聯絡處理
            dialogCancel();
        });

        setButtonOkText(0);

        closeDialogCountdown = new CloseDialogOnThreadHandler(getHandlerMain());
        buttonControlCountdown = new HandlerMainCountdown(getHandlerMain()) {
            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected void execute(long countdown, HandlerMain handlerMain) {
                if (countdown < 2) {
                    handlerMain.start("devShippedProduct", Option.ENABLED_TRUE.getOption(), "enabled true");
                }
            }

            @Override
            protected void close(HandlerMain handlerMain) {
                handlerMain.start("devShippedProduct", Option.ENABLED_TRUE.getOption(), "enabled true");
            }
        };

    }

    private void openLatticeCabinet() throws LogsSecurityException, LogsUnsupportedOperationException, LogsIOException {
        getLogs().info("----- openLatticeCabinet -----");

        DispatchStructure dispatch = this.dispatchList.get(this.dispatchIndex);
        slot = dispatch.getSlot();
        DevFlowerController devFlowerController = new DevFlowerController(setHandlerMain());
        devFlowerController.devSendCustomCommand(slot);
        devFlowerController.start();
        setTextViewCountdown(15,slot);

        ProductStructure product = dispatch.getProduct();
        int field = dispatch.getField();
        int increase = 1;

        try {
            int slotCount = MyApp.getInstance().getSlotData(field, slot).getCount();
            int remaining = slotCount-increase; //計算剩餘數量
            MyApp.getInstance().getSlotData(field, slot).setCount(remaining);
            MyApp.getInstance().getReportDispatchInfoData().setRemaining(remaining);
        } catch (LogsEmptyException e) {
            getLogs().warning(e);
        }

        int count = dispatch.getCount();
        //設定回傳資料
        int price = product.getRealPrice() * count;
            MyApp.getInstance().setReportDispatchInfoData(new ReportDispatchInfoStructure(
                MyApp.getInstance().getReportFlowInfoData().getReportFlowId(),
                MyApp.getInstance().getReportFlowInfoData().getFlowType(),
                product.getProductID(),
                slot,
                price*increase,
                MyApp.getInstance().getReportFlowInfoData().getOrderId(),
                0,//increase,//這裡本來是increase，但鮮花機只會有一個商品，若出貨成功，庫存一定是變成0，所以直接給值為0
                MyApp.getInstance().getReportFlowInfoData().getFlowBarCode(),
               "",
               0,
                price,
               0
            ));

        try {
            httpAPI.reportDispatchInfo(MyApp.getInstance().getReportDispatchInfoData());
        } catch (LogsSettingEmptyException e) {
            throw new RuntimeException(e);
        } catch (LogsParseException e) {
            throw new RuntimeException(e);
        }

        /*商品圖片及商品名稱*/

        binding.textProductName.setText(product.getProductName());

        try {
              new ImageGlide(getContext()).fileload(product.getProductImg(), binding.imageProductPicture);
        } catch (LogsEmptyException e) {
              getLogs().warning(e);
        }

        getSrcHandlerMain().start(getClass().getSimpleName(), FontendActivity.Option.RESET_DATA.getOption(), "update data");
        new Handler().postDelayed(() -> {
            dialogCancel(); // 關閉當前 Activity
            slot = 0;
        }, 15000);

        //saveData();
        getLogs().info("開啟格子櫃號"+slot);
    }

    public void closeButtonOk() {
        getLogs().info("關閉按鈕");
        binding.buttonOk.setTextColor(Color.GRAY);
        binding.buttonOk.setEnabled(false);
        binding.buttonOk.setTextColor(Color.GRAY);
        binding.buttonOk.setEnabled(false);
    }

    public void openButtonOk() {
        getLogs().info("開啟按鈕");
        binding.buttonOk.setTextColor(Color.BLACK);
        binding.buttonOk.setEnabled(true);
        binding.buttonOk.setTextColor(Color.BLACK);
        binding.buttonOk.setEnabled(true);
    }

    public void dialogCancel() {
        closeDialogCountdown.shutdown();
        int buyListSize = MyApp.getInstance().getBuyList().size();
        MyApp.getInstance().getBuyList().clear();

        if (buyListSize > 0) {
            recyclerDialogFlowerPickupListAdpter.notifyItemRangeRemoved(0, buyListSize);
        }
        cancel();
    }

    public void cancelOnThreadCountdown() {
        MyApp.getInstance().getBuyList().clear();
        cancel();
    }

    private void saveData() {
        SlotsDao slotsDao = new SlotsDao(getCtx());
        slotsDao.deleteAll();
        slotsDao.insertAll(MyApp.getInstance().getSlotMap());
        slotsDao.close();
        getLogs().info("save count:"+ MyApp.getInstance().getSlotList(SlotField.FLOWER.getField()).size());
    }

    public void setButtonOkText(long countdown) {
        if (countdown <= 0) {
            binding.buttonOk.setText(getContext().getString(R.string.pickup_confirmation));//取貨確認
        } else {
            binding.buttonOk.setText(getContext().getString(R.string.pickup_confirmation)+"(" + countdown + ")");
        }
    }

    public void setTextViewCountdown(long countdown){
        if (countdown <= 0) {
            setTextViewCountdown(getCtx().getString(R.string.pick_up_goods_within_15_seconds_after_pick_up_port_opened), 75);//取貨口開啟15秒內取貨
        } else {
            setTextViewCountdown(getCtx().getString(R.string.pickup_port_open)+"(" + countdown + ")"+getCtx().getString(R.string.pick_up_within), 75);//取貨口開啟,秒內取貨
        }
    }

    public void setTextViewCountdown(long countdown,int slot){
        if (countdown <= 0) {
            setTextViewCountdown("格子櫃第"+slot+"號格子開啟\n取貨完請關上格子門，謝謝！", 70);//取貨口開啟15秒內取貨
        } else {
            //setTextViewCountdown("格子櫃第"+slot+"號格子開啟\n取貨口開啟"+"(" + countdown + ")"+"秒內取貨\n取貨完請關上格子門，謝謝！", 70);//取貨口開啟,秒內取貨
            setTextViewCountdown("格子櫃第"+slot+"號格子開啟\n取貨完請關上格子門，謝謝！", 70);//取貨口開啟,秒內取貨
        }
    }

    public void setTextViewSmall(String message) {
        setTextViewCountdown(message, 60);
    }
    public void setTextViewCountdown(String message, int size) {
        if (isChangeStatus) {
            binding.dispatchtips.setText(message);
            binding.dispatchtips.setTextSize(size);
        }
    }

    public class CloseDialogOnThreadHandler extends HandlerMainCountdown {
        public CloseDialogOnThreadHandler(HandlerMain handlerMain) {
            super(handlerMain);
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void close(HandlerMain handlerMain) {
            handlerMain.start(getClass().getSimpleName(), Option.NEXT_PRODUCT.getOption(), "next product");
        }

        @Override
        protected void execute(long countdown, HandlerMain handlerMain) {
            handlerMain.start(getClass().getSimpleName(), Option.SET_COUNTDOWN_TEXT.getOption(), String.valueOf(countdown));
        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }
}
